package com.hyopt.common.base;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.List;

/**
 * 工具类
 *
 * @author wanglei
 * @date 2019-08-24 09:41:42
 */
public class BaseServiceUtils {

	/**
	 * 集合类型转换
	 *
	 * @param list
	 * @param clazz
	 * @param <V>
	 * @return
	 */
	public static <T, V> List<V> convertToListVo(List<T> list, Class<V> clazz) {
		if (ObjectUtil.isNull(list)) {
			return null;
		}
		List<V> voList = CollUtil.newArrayList();
		if (CollUtil.isNotEmpty(list)) {
			for (T entity : list) {
				voList.add(BeanUtil.toBean(entity, clazz));
			}
		}
		return voList;
	}

	public static <T, V> List<V> convertToListVo(List<T> list, Class<V> clazz, ConvertFun<Object, V>... funArray) {
		if (ObjectUtil.isNull(list)) {
			return null;
		}
		List<V> voList = CollUtil.newArrayList();
		if (CollUtil.isNotEmpty(list)) {
			for (T entity : list) {
				V vo = BaseServiceUtils.toBeanAndCovert(entity, clazz, funArray);
				voList.add(vo);
			}
		}
		return voList;
	}

	public static boolean isFieldClssTrue(Class beanClazz, String key, Class valueClass, Class... argumentClass) {
		if (ObjectUtil.isNull(beanClazz)) {
			return false;
		}
		Field field = ReflectUtil.getField(beanClazz, key);
		if (ObjectUtil.isNull(field)) {
			return false;
		}
		if (!ClassUtil.isAssignable(field.getType(), valueClass)) {
			return false;
		}
		if (ArrayUtil.isNotEmpty(argumentClass)) {
			Type[] arguments = TypeUtil.getTypeArguments(TypeUtil.getType(field));
			if (ArrayUtil.isEmpty(arguments) || arguments.length < argumentClass.length) {
				return false;
			}
			for (int i = 0; i < argumentClass.length; i++) {
				Type type = arguments[i];
				Class clazz = argumentClass[i];
				if (!StrUtil.equals(type.getTypeName(), clazz.getName())) {
					return false;
				}
			}
		}
		return true;
	}

	public static <V> V toBeanAndCovert(Object entity, Class<V> clazz, ConvertFun<Object, V>... funArray) {
		if (ObjectUtil.isNull(entity)) {
			return null;
		}
		V vo = BeanUtil.toBean(entity, clazz);
		if (ArrayUtil.isNotEmpty(funArray)) {
			for (ConvertFun<Object, V> fun : funArray) {
				if (ObjectUtil.isNotNull(fun) && ObjectUtil.isNotNull(entity) && ObjectUtil.isNotNull(vo)) {
					vo = fun.convert(entity, vo);
				}
			}
		}
		return vo;
	}

	public static <V, M> IPage<V> convertToPageVo(IPage<M> iPage, Class<V> clazz, ConvertFun<Object, V>... funArray) {
		List<V> voList = convertToListVo(iPage.getRecords(), clazz, funArray);
		Page<V> page = new Page<>(iPage.getCurrent(), iPage.getSize(), iPage.getTotal(), iPage.isSearchCount());
		page.setRecords(voList);
		return page;
	}

}
